package fr.utt.lo02.CrazyEights.view;

import java.awt.*;
import java.awt.event.*;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;

import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;

import fr.utt.lo02.CrazyEights.model.Game;
import fr.utt.lo02.CrazyEights.model.players.Human;
import fr.utt.lo02.CrazyEights.model.players.Player;
import fr.utt.lo02.CrazyEights.view.GamePanel.EightPlayersPanel;
import fr.utt.lo02.CrazyEights.view.GamePanel.FivePlayersPanel;
import fr.utt.lo02.CrazyEights.view.GamePanel.FourPlayersPanel;
import fr.utt.lo02.CrazyEights.view.GamePanel.SevenPlayersPanel;
import fr.utt.lo02.CrazyEights.view.GamePanel.SixPlayersPanel;
import fr.utt.lo02.CrazyEights.view.GamePanel.ThreePlayersPanel;
import fr.utt.lo02.CrazyEights.view.GamePanel.TwoPlayersPanel;


/**
 * Represents the main window
 * @author Jeremy
 *
 */
public class MainWindow extends JFrame implements Observer{

	private static final long serialVersionUID = 1L;
	public final static int cardWidth = 75;
	public final static int cardHeight = 108;
	
	public final static int width = 1024;
	public final static int height = 768;
	
	private JMenuBar menuBar = new JMenuBar();
	private JMenu menu1 = new JMenu("Game");
	private JMenu menu2 = new JMenu("Background Color");
	private JMenu menu3 = new JMenu("Help");
	
	private JMenuItem item1 = new JMenuItem("New Game");
	private JMenuItem item2 = new JMenuItem("Quit");
	private JMenuItem item3 = new JMenuItem("I'm Feeling Lucky");
	private JMenuItem item4 = new JMenuItem("Rules");
	private JMenuItem item5 = new JMenuItem("Save");
	private JMenuItem item6 = new JMenuItem("Load");
	
	private JRadioButton jrb1 = new JRadioButton("Green");
	private JRadioButton jrb2 = new JRadioButton("Blue");
	private JRadioButton jrb3 = new JRadioButton("Red");
	private JRadioButton jrb4 = new JRadioButton("Purple");
	
	private ButtonGroup bg = new ButtonGroup();
	
	private Container container = this.getContentPane();
	
	private Color backgroundColor = Color.GREEN.darker().darker().darker();
	
	/**
	 * Create the main window
	 */
	public MainWindow(){
		Game.getInstance().addObserver(this);
		this.setTitle("Crazy Eights");
        this.setSize(width,height);
        this.setLocationRelativeTo(null);
        container.setBackground(backgroundColor);
        this.setResizable(false);
        
        // New Game Listener
        item1.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				Settings();
			}				
		});
        
        // Quit Listener
        item2.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				System.exit(0);
			}				
		});
        
        jrb1.setSelected(true);
        bg.add(jrb1);
        bg.add(jrb2);
        bg.add(jrb3);
        bg.add(jrb4);
        
        menu2.add(jrb1);
        menu2.add(jrb2);
        menu2.add(jrb3);
        menu2.add(jrb4);
        
        jrb1.addActionListener(new BackgroundColorState());
        jrb2.addActionListener(new BackgroundColorState());
        jrb3.addActionListener(new BackgroundColorState());
        jrb4.addActionListener(new BackgroundColorState());
        
        item5.addActionListener(new SaveState());
        item6.addActionListener(new LoadState());
        
        this.menu1.add(item1);
        this.menu1.add(item5);
        item5.setEnabled(false);
        this.menu1.add(item6);
        this.menu1.add(menu2);
        this.menu1.add(item2);
        
        item3.addActionListener(new ImFeelingLuckyState());
        item4.addActionListener(new RulesState());
        
        this.menu3.add(item3);
        item3.setEnabled(false);
        this.menu3.add(item4);
        
        this.menuBar.add(menu1);
        this.menuBar.add(menu3);
        
        this.setJMenuBar(menuBar);
        
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        this.setContentPane(container);
        
        this.setVisible(true);
	}
	
	/**
	 * Create and show the dialog to set game Settings
	 */
	public void Settings(){
		GameSettingsDialog settings = new GameSettingsDialog(this);
		settings.showGameSettingsDialog();
	}
	
	/**
	 * Initialize a new game
	 */
	public void newGame(){
		Game.getInstance().init();
		item3.setEnabled(true);
		item5.setEnabled(true);
	}
	
	/**
	 * Refresh the display of players
	 */
	public void repaintGame(){
		if(Game.getInstance().isInitialized()){
			container.setVisible(false);
			container.removeAll();
			switch(Game.getInstance().getPlayersPanels().size()){
			case 2:
				TwoPlayersPanel twoPlayersPanel = new TwoPlayersPanel();
				twoPlayersPanel.setBackground(backgroundColor);
				this.add(twoPlayersPanel);
				break;
			case 3:
				ThreePlayersPanel threePlayersPanel = new ThreePlayersPanel();
				threePlayersPanel.setBackground(backgroundColor);
				this.add(threePlayersPanel);
				break;
			case 4:
				FourPlayersPanel fourPlayersPanel = new FourPlayersPanel();
				fourPlayersPanel.setBackground(backgroundColor);
				this.add(fourPlayersPanel);
				break;
			case 5:
				FivePlayersPanel fivePlayersPanel = new FivePlayersPanel();
				fivePlayersPanel.setBackground(backgroundColor);
				this.add(fivePlayersPanel);
				break;
			case 6:
				SixPlayersPanel sixPlayersPanel = new SixPlayersPanel();
				sixPlayersPanel.setBackground(backgroundColor);
				this.add(sixPlayersPanel);
				break;
			case 7:
				SevenPlayersPanel sevenPlayersPanel = new SevenPlayersPanel();
				sevenPlayersPanel.setBackground(backgroundColor);
				this.add(sevenPlayersPanel);
				break;
			case 8:
				EightPlayersPanel eightPlayersPanel = new EightPlayersPanel();
				eightPlayersPanel.setBackground(backgroundColor);
				this.add(eightPlayersPanel);
			}
			Game.getInstance().getDiscardPilePanel().setBackground(backgroundColor);
			Game.getInstance().getStockPilePanel().setBackground(backgroundColor);
			for(PlayerPanel pp : Game.getInstance().getPlayersPanels()){
				pp.setBackground(backgroundColor);
			}
			container.setVisible(true);
		}
	}
	
	/**
	 * Change the window content when the game is ended
	 */
	public void endGame(){
		container.setVisible(false);
		if(Game.getInstance().isGameEnded()){
			item3.setEnabled(false);
			item5.setEnabled(false);
			container.removeAll();
			container.setLayout(new GridBagLayout());
			GridBagConstraints c = new GridBagConstraints();
			JLabel winner = new JLabel(Game.getInstance().getPlayersList().getRanking().get(0).getName()+" is the winner!");
			winner.setFont(new Font("Serif", Font.BOLD, 48));
			winner.setForeground(Color.white);
			JButton newGame = new JButton("New Game");
			JButton quit = new JButton("Quit");
			
			c.anchor = GridBagConstraints.CENTER;
			c.gridy = 0;
			c.gridwidth = 2;
			container.add(winner,c);
			int rank =1;
			int gridy = c.gridy+1;
			c.gridy = gridy;
			for(Player p : Game.getInstance().getPlayersList().getRanking()){
				container.add(new JLabel("<html><font color = #ffffff>"+rank+". "+p.getName()+" ==> "+p.getPoints()+" points</font></html>"),c);
				rank++;
				gridy++;
				c.gridy = gridy;
			}
			c.gridx=0;
			c.weightx = 0.5;
			c.gridwidth = 1;
			c.anchor = GridBagConstraints.LINE_END;
			container.add(newGame,c);
			c.gridx = 1;
			c.anchor = GridBagConstraints.LINE_START;
			container.add(quit,c);
			quit.addActionListener(new quitState());
			newGame.addActionListener(new newGameState());
		}
		container.setVisible(true);
	}
	
	public void update(Observable o, Object arg){
		if(Game.getInstance().isGameEnded()){
			endGame();
		}
		else if(Game.getInstance().getChangeSuit()){
			if(Game.getInstance().getPlayersList().getCurrentPlayer() instanceof Human){
				ChooseSuitDialog chooseSuit = new ChooseSuitDialog(this);
				chooseSuit.showChooseSuitDialog();
			}
		}
		else{
			repaintGame();
		}
	}
	
	/**
	 * ActionListener for the new game menu
	 * @author Jeremy
	 *
	 */
	class newGameState implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			Settings();
		}
	}
	
	/**
	 * ActionListener for the quit menu
	 * @author Jeremy
	 *
	 */
	class quitState implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			System.exit(0);
		}
	}
	
	/**
	 * ActionListener for the change background color menu
	 * @author Jeremy
	 *
	 */
	class BackgroundColorState implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			if(jrb1.isSelected()){
				backgroundColor = Color.GREEN.darker().darker().darker();
			}else if(jrb2.isSelected()){
				backgroundColor = Color.BLUE.darker().darker().darker();
			}else if(jrb3.isSelected()){
				backgroundColor = Color.RED.darker().darker().darker();
			}else if(jrb4.isSelected()){
				backgroundColor = new Color(255,0,255).darker().darker().darker();
			}
			if(Game.getInstance().isGameEnded()){
				endGame();
			}else{
				repaintGame();
			}
			container.setBackground(backgroundColor);
		}
	}
	
	/**
	 * ActionListener for the I'm Feeling Lucky menu
	 * @author Jeremy
	 *
	 */
	class ImFeelingLuckyState implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			if(Game.getInstance().getPlayersList().getCurrentPlayer()!=null){
				if(Game.getInstance().getPlayersList().getCurrentPlayer() instanceof Human){
					Game.getInstance().getPlayersList().getCurrentPlayer().play();
				}
			}
		}
	}
	
	/**
	 * Create a JPanel to show rules from rules.txt
	 */
	public void showRules(){
		String content = "";
		try {
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("resources/rules.txt")));
			byte[] buf = new byte[8];
			String read;
			while(bis.read(buf) != -1){
				read = new String(buf,"ISO-8859-1");
				  content+=read;
			};
			bis.close();
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e2) {
			e2.printStackTrace();
		}
		JEditorPane editorPane  = new JEditorPane("text/html", content);
		editorPane.setEditable(false);
		editorPane.setCaretPosition(0);
		JScrollPane scrollPane = new JScrollPane(editorPane);
		JDialog rules = new JDialog();
		rules.setSize(1024, 768);
		rules.add(scrollPane);
		rules.setTitle("Rules");
		rules.setResizable(false);
		rules.setLocationRelativeTo(null);
		rules.setVisible(true);
	}
	
	class RulesState implements ActionListener{
		public void actionPerformed(ActionEvent e){
			showRules();
		}
	}
	
	/**
	 * ActionListener for the save menu
	 * @author Jeremy
	 *
	 */
	class SaveState implements ActionListener{
		public void actionPerformed(ActionEvent e){
			if(Game.getInstance().isInitialized()){
				JFileChooser fileChooser = new JFileChooser();
				FileNameExtensionFilter filter = new FileNameExtensionFilter("Crazy Eights Saves (.ces)", "ces");
				fileChooser.setFileFilter(filter);
				fileChooser.showSaveDialog(null);
				File file = fileChooser.getSelectedFile();
				Game.getInstance().save(file);
			}
		}
	}
	
	/**
	 * ActionListener for the load menu
	 * @author Jeremy
	 *
	 */
	class LoadState implements ActionListener{
		public void actionPerformed(ActionEvent e){
			JFileChooser fileChooser = new JFileChooser();
			FileNameExtensionFilter filter = new FileNameExtensionFilter("Crazy Eights Saves (.ces)", "ces");
			fileChooser.setFileFilter(filter);
			fileChooser.showOpenDialog(null);
			File file = fileChooser.getSelectedFile();
			Game.getInstance().load(file);
			if(file!=null){
				item3.setEnabled(true);
				item5.setEnabled(true);
			}
			repaintGame();
		}
	}
}
